<template>
  <codemirror
    v-model="code"
    placeholder="Code goes here..."
    :style="{ height: getHeight }"
    :autofocus="false"
    :indent-with-tab="true"
    :tab-size="2"
    :extensions="mode === 'js' ? extensionsJS : extensionsJSON"
    @ready="handleReady"
    @change="handleChange"
  />
</template>

<script lang="ts" setup>
  import { PropType, defineComponent, ref, shallowRef, computed } from 'vue';
  import { Codemirror } from 'vue-codemirror';
  import { json } from '@codemirror/lang-json';
  import { javascript } from '@codemirror/lang-javascript';
  import { vscodeDark } from '@uiw/codemirror-theme-vscode';
  import { oneDark } from '@codemirror/theme-one-dark';

  const props = defineProps({
    code: {
      type: String,
      default: '',
    },
    height: {
      type: Number,
      default: 400,
    },
    mode: {
      type: String,
      default: 'js',
    },
  });

  const code = computed(() => props.code);

  const getHeight = computed(() => `${props.height}px`);

  const extensionsJSON = [json(), vscodeDark];
  const extensionsJS = [javascript({ typescript: true }), vscodeDark];

  const view = shallowRef();
  const handleReady = (payload: any) => {
    view.value = payload.view;
  };

  // Status is available at all times via Codemirror EditorView
  const getCodemirrorStates = () => {
    const state = view.value.state;
    const ranges = state.selection.ranges;
    const selected = ranges.reduce(
      (r: any, range: any) => r + range.to - range.from,
      0,
    );
    const cursor = ranges[0].anchor;
    const length = state.doc.length;
    const lines = state.doc.lines;
    // more state info ...
    // return ...
  };

  function handleChange(value: string, viewUpdate: any) {}
</script>
